package cn.jingyuan.owl.utils.core.convert;

import cn.jingyuan.owl.utils.core.CharsetUtils;
import cn.jingyuan.owl.utils.core.ClassUtils;
import cn.jingyuan.owl.utils.core.HexUtils;
import cn.jingyuan.owl.utils.core.StringUtils;
import cn.jingyuan.owl.utils.core.convert.impl.CollectionConverter;
import cn.jingyuan.owl.utils.core.convert.impl.GenericEnumConverter;
import cn.jingyuan.owl.utils.core.convert.impl.MapConverter;
import cn.jingyuan.owl.utils.core.lang.Assert;
import cn.jingyuan.owl.utils.core.lang.TypeReference;
import cn.jingyuan.owl.utils.core.text.UnicodeUtils;

import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 类型转换器
 */
public class Convert {

    /**
     * 转换为字符串<br>
     * 如果给定的值为 null，或者转换失败，返回默认值<br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @param defaultValue 转换错误时的默认值
     *
     * @return 结果
     */
    public static String toString(Object value, String defaultValue) {
        return convertQuietly(String.class, value, defaultValue);
    }

    /**
     * 转换为字符串<br>
     * 如果给定的值为 <code>null</code>，或者转换失败，返回默认值 <code>null</code><br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     *
     * @return 结果
     */
    public static String toString(Object value) {
        return toString(value, null);
    }

    /**
     * 转换为 String 数组
     *
     * @param value 被转换的值
     *
     * @return String 数组
     */
    public static String[] toStrArray(Object value) {
        return convert(String[].class, value);
    }

    /**
     * 转换为字符<br>
     * 如果给定的值为 null，或者转换失败，返回默认值<br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @param defaultValue 转换错误时的默认值
     *
     * @return 结果
     */
    public static Character toChar(Object value, Character defaultValue) {
        return convertQuietly(Character.class, value, defaultValue);
    }

    /**
     * 转换为字符<br>
     * 如果给定的值为 <code>null</code>，或者转换失败，返回默认值 <code>null</code><br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     *
     * @return 结果
     */
    public static Character toChar(Object value) {
        return toChar(value, null);
    }

    /**
     * 转换为 Character 数组
     *
     * @param value 被转换的值
     *
     * @return Character 数组
     */
    public static Character[] toCharArray(Object value) {
        return convert(Character[].class, value);
    }

    /**
     * 转换为 byte<br>
     * 如果给定的值为 <code>null</code>，或者转换失败，返回默认值<br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @param defaultValue 转换错误时的默认值
     *
     * @return 结果
     */
    public static Byte toByte(Object value, Byte defaultValue) {
        return convertQuietly(Byte.class, value, defaultValue);
    }

    /**
     * 转换为 byte<br>
     * 如果给定的值为 <code>null</code>，或者转换失败，返回默认值 <code>null</code><br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     *
     * @return 结果
     */
    public static Byte toByte(Object value) {
        return toByte(value, null);
    }

    /**
     * 转换为 Byte 数组
     *
     * @param value 被转换的值
     *
     * @return Byte 数组
     */
    public static Byte[] toByteArray(Object value) {
        return convert(Byte[].class, value);
    }

    /**
     * 转换为 Short<br>
     * 如果给定的值为 <code>null</code>，或者转换失败，返回默认值<br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @param defaultValue 转换错误时的默认值
     *
     * @return 结果
     */
    public static Short toShort(Object value, Short defaultValue) {
        return convertQuietly(Short.class, value, defaultValue);
    }

    /**
     * 转换为 Short<br>
     * 如果给定的值为 <code>null</code>，或者转换失败，返回默认值 <code>null</code><br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     *
     * @return 结果
     */
    public static Short toShort(Object value) {
        return toShort(value, null);
    }

    /**
     * 转换为 Short 数组
     *
     * @param value 被转换的值
     *
     * @return Short 数组
     */
    public static Short[] toShortArray(Object value) {
        return convert(Short[].class, value);
    }

    /**
     * 转换为 Number<br>
     * 如果给定的值为空，或者转换失败，返回默认值<br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @param defaultValue 转换错误时的默认值
     *
     * @return 结果
     */
    public static Number toNumber(Object value, Number defaultValue) {
        return convertQuietly(Number.class, value, defaultValue);
    }

    /**
     * 转换为 Number<br>
     * 如果给定的值为空，或者转换失败，返回默认值<code>null</code><br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     *
     * @return 结果
     */
    public static Number toNumber(Object value) {
        return toNumber(value, null);
    }

    /**
     * 转换为 Number 数组
     *
     * @param value 被转换的值
     *
     * @return Number 数组
     */
    public static Number[] toNumberArray(Object value) {
        return convert(Number[].class, value);
    }

    /**
     * 转换为 int<br>
     * 如果给定的值为空，或者转换失败，返回默认值<br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @param defaultValue 转换错误时的默认值
     *
     * @return 结果
     */
    public static Integer toInt(Object value, Integer defaultValue) {
        return convertQuietly(Integer.class, value, defaultValue);
    }

    /**
     * 转换为 int<br>
     * 如果给定的值为<code>null</code>，或者转换失败，返回默认值<code>null</code><br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     *
     * @return 结果
     */
    public static Integer toInt(Object value) {
        return toInt(value, null);
    }

    /**
     * 转换为 Integer 数组<br>
     *
     * @param value 被转换的值
     *
     * @return 结果
     */
    public static Integer[] toIntArray(Object value) {
        return convert(Integer[].class, value);
    }

    /**
     * 转换为 long<br>
     * 如果给定的值为空，或者转换失败，返回默认值<br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @param defaultValue 转换错误时的默认值
     *
     * @return 结果
     */
    public static Long toLong(Object value, Long defaultValue) {
        return convertQuietly(Long.class, value, defaultValue);
    }

    /**
     * 转换为 long<br>
     * 如果给定的值为<code>null</code>，或者转换失败，返回默认值<code>null</code><br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     *
     * @return 结果
     */
    public static Long toLong(Object value) {
        return toLong(value, null);
    }

    /**
     * 转换为 Long 数组<br>
     *
     * @param value 被转换的值
     *
     * @return 结果
     */
    public static Long[] toLongArray(Object value) {
        return convert(Long[].class, value);
    }

    /**
     * 转换为 double<br>
     * 如果给定的值为空，或者转换失败，返回默认值<br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @param defaultValue 转换错误时的默认值
     *
     * @return 结果
     */
    public static Double toDouble(Object value, Double defaultValue) {
        return convertQuietly(Double.class, value, defaultValue);
    }

    /**
     * 转换为 double<br>
     * 如果给定的值为空，或者转换失败，返回默认值<code>null</code><br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     *
     * @return 结果
     */
    public static Double toDouble(Object value) {
        return toDouble(value, null);
    }

    /**
     * 转换为 Double 数组<br>
     *
     * @param value 被转换的值
     *
     * @return 结果
     */
    public static Double[] toDoubleArray(Object value) {
        return convert(Double[].class, value);
    }

    /**
     * 转换为 Float<br>
     * 如果给定的值为空，或者转换失败，返回默认值<br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @param defaultValue 转换错误时的默认值
     *
     * @return 结果
     */
    public static Float toFloat(Object value, Float defaultValue) {
        return convertQuietly(Float.class, value, defaultValue);
    }

    /**
     * 转换为 Float<br>
     * 如果给定的值为空，或者转换失败，返回默认值<code>null</code><br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     *
     * @return 结果
     */
    public static Float toFloat(Object value) {
        return toFloat(value, null);
    }

    /**
     * 转换为 Float 数组<br>
     *
     * @param value 被转换的值
     *
     * @return 结果
     */
    public static Float[] toFloatArray(Object value) {
        return convert(Float[].class, value);
    }

    /**
     * 转换为 boolean<br>
     * String 支持的值为：true、false、yes、ok、no，1,0 如果给定的值为空，或者转换失败，返回默认值<br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @param defaultValue 转换错误时的默认值
     *
     * @return 结果
     */
    public static Boolean toBool(Object value, Boolean defaultValue) {
        return convertQuietly(Boolean.class, value, defaultValue);
    }

    /**
     * 转换为 boolean<br>
     * 如果给定的值为空，或者转换失败，返回默认值<code>null</code><br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     *
     * @return 结果
     */
    public static Boolean toBool(Object value) {
        return toBool(value, null);
    }

    /**
     * 转换为 Boolean 数组<br>
     *
     * @param value 被转换的值
     *
     * @return 结果
     */
    public static Boolean[] toBooleanArray(Object value) {
        return convert(Boolean[].class, value);
    }

    /**
     * 转换为 BigInteger<br>
     * 如果给定的值为空，或者转换失败，返回默认值<br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @param defaultValue 转换错误时的默认值
     *
     * @return 结果
     */
    public static BigInteger toBigInteger(Object value, BigInteger defaultValue) {
        return convertQuietly(BigInteger.class, value, defaultValue);
    }

    /**
     * 转换为 BigInteger<br>
     * 如果给定的值为空，或者转换失败，返回默认值<code>null</code><br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     *
     * @return 结果
     */
    public static BigInteger toBigInteger(Object value) {
        return toBigInteger(value, null);
    }

    /**
     * 转换为 BigDecimal<br>
     * 如果给定的值为空，或者转换失败，返回默认值<br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @param defaultValue 转换错误时的默认值
     *
     * @return 结果
     */
    public static BigDecimal toBigDecimal(Object value, BigDecimal defaultValue) {
        return convertQuietly(BigDecimal.class, value, defaultValue);
    }

    /**
     * 转换为 BigDecimal<br>
     * 如果给定的值为空，或者转换失败，返回 null<br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     *
     * @return 结果
     */
    public static BigDecimal toBigDecimal(Object value) {
        return toBigDecimal(value, null);
    }

    /**
     * 转换为 Date<br>
     * 如果给定的值为空，或者转换失败，返回默认值<br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @param defaultValue 转换错误时的默认值
     *
     * @return 结果
     */
    public static Date toDate(Object value, Date defaultValue) {
        return convertQuietly(Date.class, value, defaultValue);
    }

    /**
     * LocalDateTime<br>
     * 如果给定的值为空，或者转换失败，返回默认值<br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @param defaultValue 转换错误时的默认值
     *
     * @return 结果
     */
    public static Date toLocalDateTime(Object value, Date defaultValue) {
        return convertQuietly(LocalDateTime.class, value, defaultValue);
    }

    /**
     * Instant<br>
     * 如果给定的值为空，或者转换失败，返回默认值<br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @param defaultValue 转换错误时的默认值
     *
     * @return 结果
     */
    public static Date toInstant(Object value, Date defaultValue) {
        return convertQuietly(Instant.class, value, defaultValue);
    }

    /**
     * 转换为 Date<br>
     * 如果给定的值为空，或者转换失败，返回<code>null</code><br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     *
     * @return 结果
     */
    public static Date toDate(Object value) {
        return toDate(value, null);
    }

    /**
     * 转换为 Enum 对象<br>
     * 如果给定的值为空，或者转换失败，返回默认值<br>
     *
     * @param <E> 枚举类型
     * @param clazz Enum 的 Class
     * @param value 值
     * @param defaultValue 默认值
     *
     * @return Enum
     */
    public static <E extends Enum<E>> E toEnum(Class<E> clazz, Object value, E defaultValue) {
        return (new GenericEnumConverter<>(clazz)).convertQuietly(value, defaultValue);
    }

    /**
     * 转换为 Enum 对象<br>
     * 如果给定的值为空，或者转换失败，返回默认值<code>null</code><br>
     *
     * @param <E> 枚举类型
     * @param clazz Enum 的 Class
     * @param value 值
     *
     * @return Enum
     */
    public static <E extends Enum<E>> E toEnum(Class<E> clazz, Object value) {
        return toEnum(clazz, value, null);
    }

    /**
     * 转换为集合类
     *
     * @param collectionType 集合类型
     * @param elementType 集合中元素类型
     * @param value 被转换的值
     *
     * @return {@link Collection}
     */
    public static Collection<?> toCollection(Class<?> collectionType, Class<?> elementType, Object value) {
        return new CollectionConverter(collectionType, elementType).convert(value, null);
    }

    /**
     * 转换为 ArrayList，元素类型默认 Object
     *
     * @param value 被转换的值
     *
     * @return {@link List}
     */
    public static List<?> toList(Object value) {
        return convert(List.class, value);
    }

    /**
     * 转换为 ArrayList
     *
     * @param <T> 元素类型
     * @param elementType 集合中元素类型
     * @param value 被转换的值
     *
     * @return {@link List}
     */
    public static <T> List<T> toList(Class<T> elementType, Object value) {
        return (List<T>) toCollection(ArrayList.class, elementType, value);
    }

    /**
     * 转换为 Map
     *
     * @param <K> 键类型
     * @param <V> 值类型
     * @param keyType 键类型
     * @param valueType 值类型
     * @param value 被转换的值
     *
     * @return {@link Map}
     */
    public static <K, V> Map<K, V> toMap(Class<K> keyType, Class<V> valueType, Object value) {
        return (Map<K, V>) new MapConverter(HashMap.class, keyType, valueType).convert(value, null);
    }

    /**
     * 转换值为指定类型，类型采用字符串表示
     *
     * @param <T> 目标类型
     * @param className 类的字符串表示
     * @param value 值
     *
     * @return 转换后的值
     *
     * @throws ConvertException 转换器不存在
     */
    public static <T> T convertByClassName(String className, Object value) throws ConvertException {
        return (T) convert(ClassUtils.loadClass(className), value);
    }

    /**
     * 转换值为指定类型
     *
     * @param <T> 目标类型
     * @param type 类型
     * @param value 值
     *
     * @return 转换后的值
     *
     * @throws ConvertException 转换器不存在
     */
    public static <T> T convert(Class<T> type, Object value) throws ConvertException {
        return convert((Type) type, value);
    }

    /**
     * 转换值为指定类型
     *
     * @param <T> 目标类型
     * @param reference 类型参考，用于持有转换后的泛型类型
     * @param value 值
     *
     * @return 转换后的值
     *
     * @throws ConvertException 转换器不存在
     */
    public static <T> T convert(TypeReference<T> reference, Object value) throws ConvertException {
        return convert(reference.getType(), value, null);
    }

    /**
     * 转换值为指定类型
     *
     * @param <T> 目标类型
     * @param type 类型
     * @param value 值
     *
     * @return 转换后的值
     *
     * @throws ConvertException 转换器不存在
     */
    public static <T> T convert(Type type, Object value) throws ConvertException {
        return convert(type, value, null);
    }

    /**
     * 转换值为指定类型
     *
     * @param <T> 目标类型
     * @param type 类型
     * @param value 值
     * @param defaultValue 默认值
     *
     * @return 转换后的值
     *
     * @throws ConvertException 转换器不存在
     */
    public static <T> T convert(Class<T> type, Object value, T defaultValue) throws ConvertException {
        return convert((Type) type, value, defaultValue);
    }

    /**
     * 转换值为指定类型
     *
     * @param <T> 目标类型
     * @param type 类型
     * @param value 值
     * @param defaultValue 默认值
     *
     * @return 转换后的值
     *
     * @throws ConvertException 转换器不存在
     */
    public static <T> T convert(Type type, Object value, T defaultValue) throws ConvertException {
        return ConverterRegistry.getInstance().convert(type, value, defaultValue);
    }

    /**
     * 转换值为指定类型，不抛异常转换<br>
     * 当转换失败时返回 {@code null}
     *
     * @param <T> 目标类型
     * @param type 目标类型
     * @param value 值
     *
     * @return 转换后的值，转换失败返回 null
     */
    public static <T> T convertQuietly(Type type, Object value) {
        return convertQuietly(type, value, null);
    }

    /**
     * 转换值为指定类型，不抛异常转换<br>
     * 当转换失败时返回默认值
     *
     * @param <T> 目标类型
     * @param type 目标类型
     * @param value 值
     * @param defaultValue 默认值
     *
     * @return 转换后的值
     */
    public static <T> T convertQuietly(Type type, Object value, T defaultValue) {
        try {
            return convert(type, value, defaultValue);
        } catch (Exception e) {
            return defaultValue;
        }
    }

    /**
     * 半角转全角
     *
     * @param input String.
     *
     * @return 全角字符串.
     */
    public static String toSBC(String input) {
        return toSBC(input, null);
    }

    /**
     * 半角转全角
     *
     * @param input String
     * @param notConvertSet 不替换的字符集合
     *
     * @return 全角字符串.
     */
    public static String toSBC(String input, Set<Character> notConvertSet) {
        final char[] c = input.toCharArray();
        for (int i = 0; i < c.length; i++) {
            if (null != notConvertSet && notConvertSet.contains(c[i])) {
                // 跳过不替换的字符
                continue;
            }

            if (c[i] == ' ') {
                c[i] = '\u3000';
            } else if (c[i] < '\177') {
                c[i] = (char) (c[i] + 65248);

            }
        }
        return new String(c);
    }

    /**
     * 全角转半角
     *
     * @param input String.
     *
     * @return 半角字符串
     */
    public static String toDBC(String input) {
        return toDBC(input, null);
    }

    /**
     * 替换全角为半角
     *
     * @param text 文本
     * @param notConvertSet 不替换的字符集合
     *
     * @return 替换后的字符
     */
    public static String toDBC(String text, Set<Character> notConvertSet) {
        if (StringUtils.isBlank(text)) {
            return text;
        }
        final char[] c = text.toCharArray();
        for (int i = 0; i < c.length; i++) {
            if (null != notConvertSet && notConvertSet.contains(c[i])) {
                // 跳过不替换的字符
                continue;
            }

            if (c[i] == '\u3000' || c[i] == '\u00a0' || c[i] == '\u2007' || c[i] == '\u202F') {
                // \u3000 是中文全角空格，\u00a0、\u2007、\u202F 是不间断空格
                c[i] = ' ';
            } else if (c[i] > '\uFF00' && c[i] < '\uFF5F') {
                c[i] = (char) (c[i] - 65248);
            }
        }

        return new String(c);
    }

    /**
     * 字符串转换成十六进制字符串，结果为小写
     *
     * @param str 待转换的 ASCII 字符串
     * @param charset 编码
     *
     * @return 16 进制字符串
     *
     * @see HexUtils#encodeHexStr(String, Charset)
     */
    public static String toHex(String str, Charset charset) {
        return HexUtils.encodeHexStr(str, charset);
    }

    /**
     * byte 数组转 16 进制串
     *
     * @param bytes 被转换的 byte 数组
     *
     * @return 转换后的值
     *
     * @see HexUtils#encodeHexStr(byte[])
     */
    public static String toHex(byte[] bytes) {
        return HexUtils.encodeHexStr(bytes);
    }

    /**
     * Hex 字符串转换为 Byte 值
     *
     * @param src Byte 字符串，每个 Byte 之间没有分隔符
     *
     * @return byte[]
     *
     * @see HexUtils#decodeHex(char[])
     */
    public static byte[] hexToBytes(String src) {
        return HexUtils.decodeHex(src.toCharArray());
    }

    /**
     * 十六进制转换字符串
     *
     * @param hexStr Byte 字符串(Byte 之间无分隔符 如:[616C6B])
     * @param charset 编码 {@link Charset}
     *
     * @return 对应的字符串
     *
     * @see HexUtils#decodeHexStr(String, Charset)
     */
    public static String hexToStr(String hexStr, Charset charset) {
        return HexUtils.decodeHexStr(hexStr, charset);
    }

    /**
     * String 的字符串转换成 unicode 的 String
     *
     * @param strText 全角字符串
     *
     * @return String 每个 unicode 之间无分隔符
     *
     * @see UnicodeUtils#toUnicode(String)
     */
    public static String strToUnicode(String strText) {
        return UnicodeUtils.toUnicode(strText);
    }

    /**
     * unicode 的 String 转换成 String 的字符串
     *
     * @param unicode Unicode 符
     *
     * @return String 字符串
     *
     * @see UnicodeUtils#toString(String)
     */
    public static String unicodeToStr(String unicode) {
        return UnicodeUtils.toString(unicode);
    }

    /**
     * 给定字符串转换字符编码<br>
     * 如果参数为空，则返回原字符串，不报错。
     *
     * @param str 被转码的字符串
     * @param sourceCharset 原字符集
     * @param destCharset 目标字符集
     *
     * @return 转换后的字符串
     *
     * @see CharsetUtils#convert(String, String, String)
     */
    public static String convertCharset(String str, String sourceCharset, String destCharset) {
        if (StringUtils.hasBlank(str, sourceCharset, destCharset)) {
            return str;
        }

        return CharsetUtils.convert(str, sourceCharset, destCharset);
    }

    /**
     * 转换时间单位
     *
     * @param sourceDuration 时长
     * @param sourceUnit 源单位
     * @param destUnit 目标单位
     *
     * @return 目标单位的时长
     */
    public static long convertTime(long sourceDuration, TimeUnit sourceUnit, TimeUnit destUnit) {
        Assert.notNull(sourceUnit, "sourceUnit is null !");
        Assert.notNull(destUnit, "destUnit is null !");
        return destUnit.convert(sourceDuration, sourceUnit);
    }

    /**
     * 原始类转为包装类，非原始类返回原类
     *
     * @param clazz 原始类
     *
     * @return 包装类
     *
     * @see BasicType#wrap(Class)
     * @see BasicType#wrap(Class)
     */
    public static Class<?> wrap(Class<?> clazz) {
        return BasicType.wrap(clazz);
    }

    /**
     * 包装类转为原始类，非包装类返回原类
     *
     * @param clazz 包装类
     *
     * @return 原始类
     *
     * @see BasicType#unWrap(Class)
     * @see BasicType#unWrap(Class)
     */
    public static Class<?> unWrap(Class<?> clazz) {
        return BasicType.unWrap(clazz);
    }

    /**
     * 将阿拉伯数字转为英文表达方式
     *
     * @param number {@link Number} 对象
     *
     * @return 英文表达式
     */
    public static String numberToWord(Number number) {
        return NumberWordFormat.format(number);
    }

    /**
     * 将阿拉伯数字转为中文表达方式
     *
     * @param number 数字
     * @param isUseTraditonal 是否使用繁体字（金额形式）
     *
     * @return 中文
     */
    public static String numberToChinese(double number, boolean isUseTraditonal) {
        return NumberChineseFormat.format(number, isUseTraditonal);
    }

    /**
     * 金额转为中文形式
     *
     * @param n 数字
     *
     * @return 中文大写数字
     */
    public static String digitToChinese(Number n) {
        if (null == n) {
            return "零";
        }
        return NumberChineseFormat.format(n.doubleValue(), true, true);
    }

    /**
     * int 转 byte
     *
     * @param intValue int 值
     *
     * @return byte 值
     */
    public static byte intToByte(int intValue) {
        return (byte) intValue;
    }

    /**
     * byte 转无符号 int
     *
     * @param byteValue byte 值
     *
     * @return 无符号 int 值
     */
    public static int byteToUnsignedInt(byte byteValue) {
        // Java 总是把 byte 当做有符处理；我们可以通过将其和 0xFF 进行二进制与得到它的无符值
        return byteValue & 0xFF;
    }

    /**
     * byte 数组转 short
     *
     * @param bytes byte 数组
     *
     * @return short 值
     */
    public static short bytesToShort(byte[] bytes) {
        return (short) (bytes[1] & 0xff | (bytes[0] & 0xff) << 8);
    }

    /**
     * short 转 byte 数组
     *
     * @param shortValue short 值
     *
     * @return byte 数组
     */
    public static byte[] shortToBytes(short shortValue) {
        byte[] b = new byte[2];
        b[1] = (byte) (shortValue & 0xff);
        b[0] = (byte) ((shortValue >> 8) & 0xff);
        return b;
    }

    /**
     * byte[]转 int 值
     *
     * @param bytes byte 数组
     *
     * @return int 值
     */
    public static int bytesToInt(byte[] bytes) {
        return bytes[3] & 0xFF |
            (bytes[2] & 0xFF) << 8 |
            (bytes[1] & 0xFF) << 16 |
            (bytes[0] & 0xFF) << 24;
    }

    /**
     * int 转 byte 数组
     *
     * @param intValue int 值
     *
     * @return byte 数组
     */
    public static byte[] intToBytes(int intValue) {
        return new byte[]{
            (byte) ((intValue >> 24) & 0xFF),
            (byte) ((intValue >> 16) & 0xFF),
            (byte) ((intValue >> 8) & 0xFF),
            (byte) (intValue & 0xFF)
        };
    }

    /**
     * long 转 byte 数组<br>
     * from: https://stackoverflow.com/questions/4485128/how-do-i-convert-long-to-byte-and-back-in-java
     *
     * @param longValue long 值
     *
     * @return byte 数组
     */
    public static byte[] longToBytes(long longValue) {
        // Magic number 8 should be defined as Long.SIZE / Byte.SIZE
        final byte[] result = new byte[8];
        for (int i = 7; i >= 0; i--) {
            result[i] = (byte) (longValue & 0xFF);
            longValue >>= 8;
        }
        return result;
    }

    /**
     * byte 数组转 long<br>
     * from: https://stackoverflow.com/questions/4485128/how-do-i-convert-long-to-byte-and-back-in-java
     *
     * @param bytes byte 数组
     *
     * @return long 值
     */
    public static long bytesToLong(byte[] bytes) {
        // Magic number 8 should be defined as Long.SIZE / Byte.SIZE
        long values = 0;
        for (int i = 0; i < 8; i++) {
            values <<= 8;
            values |= (bytes[i] & 0xff);
        }
        return values;
    }

}
